import os

from datetime import timedelta
from flask import Flask, session, render_template, redirect, url_for, flash, request
from flask_bootstrap import Bootstrap
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from sqlalchemy.testing.pickleable import User
from wtforms import StringField, PasswordField, SubmitField, RadioField, IntegerField, SelectField, HiddenField
from wtforms.validators import DataRequired, Regexp

basedir = os.path.abspath(os.path.dirname(__file__))

app = Flask(__name__)
app.config['SECRET_KEY'] = "123as41d56as4!sadfsd@1sd56b4d56n4."
# session存活时间
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)
# sqlite配置
app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:///' + os.path.join(basedir,
                                                                    'data.sqlite3') + '?check_same_thread=False'
# 降低内存消耗
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Bootstrap
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)
# 数据库迁移
migrate = Migrate(app, db)


class UserInfo(db.Model):
    __tablename__ = 'userinfo'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True)
    password = db.Column(db.String(64))
    sex = db.Column(db.String(2))
    typetels = db.relationship('TelBook', backref='user')

    def __repr__(self):
        return '<UserInfo {}>'.format(self.username)

    def __str__(self):
        return self.username


class TypeTel(db.Model):
    __tablename__ = 'typetel'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    typetels = db.relationship('TelBook', backref='type')

    def __repr__(self):
        return '<TypeTel {}>'.format(self.name)

    def __str__(self):
        return self.name


class TelBook(db.Model):
    __tablename__ = 'telbook'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    tel = db.Column(db.String(11))
    user_id = db.Column(db.Integer, db.ForeignKey('userinfo.id'))
    typetel_id = db.Column(db.Integer, db.ForeignKey('typetel.id'))

    def __repr__(self):
        return '<TelBook {}>'.format(self.name)

    def __str__(self):
        return self.name


class LoginForm(FlaskForm):
    username = StringField(label='用户名', validators=[DataRequired()])
    password = PasswordField(label='密码', validators=[DataRequired()])
    submit = SubmitField(label='登录')

class TyprTelForm(FlaskForm):
    type_tel = StringField(label='类别', validators=[DataRequired()])
    submit = SubmitField("提交")


class RegisterForm(FlaskForm):
    username = StringField(label='用户名', validators=[DataRequired()])
    password = PasswordField(label='密码', validators=[DataRequired()])
    sex = RadioField(choices=[['1', '男'], ['2', '女']])
    age = IntegerField(label='年龄')
    submit = SubmitField(label = "提交" )

class TelBookForm(FlaskForm):
    type_tel = TypeTel.query.all()
    a = []
    for i in type_tel:
        a.append([i.id,i.name])
    name = StringField(label='姓名', validators=[DataRequired()])
    phone = StringField(label="手机号", validators=[DataRequired(),
        Regexp(r'^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$', message="请输入合法手机号")])
    typetel = SelectField(label='类别',choices=a,coerce=int,validators=[DataRequired()])
    submit = SubmitField("提交")



@app.route('/login/',methods = ['GET','POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        username = str(form.username.data)
        password = str(form.password.data)
        user_pwd =  UserInfo.query.filter_by(username=username).filter_by(password=password).first()
        if not user_pwd:
            flash("用户名或密码错误！！")
            return render_template('login.html', form=form)
        session['user'] = user_pwd.id
        session['username'] = user_pwd.username
        return redirect(url_for('book'))
    return render_template('login.html',form=form)

@app.route('/register/', methods=['GET', 'POST'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        username = str(form.username.data)
        password = str(form.password.data)
        sex = str(form.sex.data)
        if not UserInfo.query.filter_by(username=username).first():
            flash("用户名重复，请重新选择一个用户名！")
            return render_template('register.html',form=form)
        try:
            user = UserInfo(username=username, password=password,sex=sex)
            db.session.add(user)
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            flash('用户注册失败！')
        return redirect(url_for('login'))
    return render_template("register.html", form=form)

@app.route('/type/',methods = ["GET" , 'POST'])
def typetel():
    form =TyprTelForm()
    if form.validate_on_submit():
        type_tel = form.type_tel.data
        if not TypeTel.query.filter_by(name=type_tel):
            flash('类别重复！！')
            return render_template('type.html',form = form)
        try:
            type_t = TypeTel(name=type_tel)
            db.session.add(type_t)
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            flash('类别添加失败！')
        return redirect(url_for('book'))
    return render_template('type.html',form=form)

@app.route('/insert_telbook/',methods = ["GET" , 'POST'])
def insert_telbook():
    form = TelBookForm()
    user_id = session.get('user')
    username = session.get('username')
    # print(user_id,username)
    if form.validate_on_submit():
        book = form.name.data
        phone = form.phone.data
        typetel = int(form.typetel.data)
        try:
            book = TelBook(name=book,tel=phone,user_id=user_id,typetel_id=typetel)
            db.session.add(book)
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            flash('新增电话簿失败！！')
        return redirect(url_for('book'))
    return render_template('insert_telbook.html', form=form,name=username)

@app.route('/',methods=['GET','POST'])
def book():
    username = session.get('username')
    tel_book = TelBook.query.all()
    name_ajax = str(request.args.get('username'))
    result_name = TelBook.query.filter(TelBook.name.like("%" + name_ajax + "%")).all()
    print(result_name)
    return render_template('book.html',name=username,book = tel_book)

@app.route('/update/<int:id>/',methods=['GET','POST'])
def update_book(id):
    book_id = id
    onetelbook = TelBook.query.filter_by(id=book_id).first()
    form = TelBookForm(name=onetelbook.name,phone=onetelbook.tel)
    user_id = session.get('user')
    if form.validate_on_submit():
        book = form.name.data
        phone = form.phone.data
        typetel = int(form.typetel.data)
        onetelbook.name=book
        onetelbook.tel = phone
        onetelbook.typetel_id = typetel
        onetelbook.user_id  = user_id
        db.session.add(onetelbook)
        db.session.commit()
        return redirect(url_for('book'))
    return render_template('update.html',form=form)


@app.route('/delete/<int:id>/',methods=['GET','POST'])
def delete_book(id):
    book_id = id
    onetelbook = TelBook.query.filter_by(id=book_id).first()
    if not onetelbook:
        flash("删除失败，不存在！")
    else:
        db.session.delete(onetelbook)
        db.session.commit()
        return redirect(url_for("book"))


if __name__ == '__main__':
    app.run()
